using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using Volo.Abp;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Domain.Repositories;
using Matrix.Configuration.DTOs;
using Matrix.Configuration.Events;

namespace Matrix.Configuration.Services
{
    /// <summary>
    /// 配置验证服务
    /// 实现基础业务规则验证
    /// </summary>
    public class ConfigurationValidationService : ITransientDependency
    {
        private readonly IRepository<ConfigurationItem, Guid> _configurationRepository;
        private readonly ILogger<ConfigurationValidationService> _logger;

        // 系统保留命名空间
        private static readonly HashSet<string> SystemNamespaces = new()
        {
            "system",
            "abp",
            "microsoft",
            "aspnetcore",
            "matrix.framework"
        };

        // 敏感配置键模式
        private static readonly List<Regex> SensitiveKeyPatterns = new()
        {
            new Regex(@"password", RegexOptions.IgnoreCase),
            new Regex(@"secret", RegexOptions.IgnoreCase),
            new Regex(@"token", RegexOptions.IgnoreCase),
            new Regex(@"key", RegexOptions.IgnoreCase),
            new Regex(@"connectionstring", RegexOptions.IgnoreCase),
            new Regex(@"credential", RegexOptions.IgnoreCase)
        };

        public ConfigurationValidationService(
            IRepository<ConfigurationItem, Guid> configurationRepository,
            ILogger<ConfigurationValidationService> logger)
        {
            _configurationRepository = configurationRepository;
            _logger = logger;
        }

        /// <summary>
        /// 验证创建配置项
        /// </summary>
        public async Task<ConfigurationValidationResult> ValidateCreateAsync(CreateConfigurationItemDto input)
        {
            var result = new ConfigurationValidationResult();

            // 基础验证
            ValidateBasicRules(input, result);

            // 业务规则验证
            await ValidateBusinessRulesAsync(input, result);

            // 安全性验证
            ValidateSecurityRules(input, result);

            // 根据错误状态设置IsValid
            result.IsValid = result.Errors.Count == 0;

            return result;
        }

        /// <summary>
        /// 验证更新配置项
        /// </summary>
        public async Task<ConfigurationValidationResult> ValidateUpdateAsync(Guid id, UpdateConfigurationItemDto input)
        {
            var result = new ConfigurationValidationResult();

            // 获取现有配置
            var existingConfig = await _configurationRepository.FirstOrDefaultAsync(x => x.Id == id);
            if (existingConfig == null)
            {
                result.AddError("配置项不存在");
                result.IsValid = false;
                return result;
            }

            // 基础验证
            ValidateBasicRulesForUpdate(input, result);

            // 业务规则验证
            ValidateBusinessRulesForUpdate(existingConfig, input, result);

            // 安全性验证
            ValidateSecurityRulesForUpdate(existingConfig, input, result);

            // 根据错误状态设置IsValid
            result.IsValid = result.Errors.Count == 0;

            return result;
        }

        /// <summary>
        /// 验证删除配置项
        /// </summary>
        public async Task<ConfigurationValidationResult> ValidateDeleteAsync(Guid id)
        {
            var result = new ConfigurationValidationResult();

            var config = await _configurationRepository.FirstOrDefaultAsync(x => x.Id == id);
            if (config == null)
            {
                result.AddError("配置项不存在");
                result.IsValid = false;
                return result;
            }

            // 检查是否为系统关键配置
            if (IsSystemCriticalConfig(config))
            {
                result.AddError("不能删除系统关键配置");
            }

            // 检查依赖关系
            await ValidateDependenciesAsync(config, result);

            // 根据错误状态设置IsValid
            result.IsValid = result.Errors.Count == 0;

            return result;
        }

        /// <summary>
        /// 批量验证配置项
        /// </summary>
        public async Task<ConfigurationValidationResult> ValidateBatchAsync(List<BatchConfigurationItemDto> configurations)
        {
            var result = new ConfigurationValidationResult();

            foreach (var config in configurations)
            {
                var createDto = new CreateConfigurationItemDto
                {
                    Namespace = config.Namespace ?? string.Empty,
                    Key = config.Key ?? string.Empty,
                    Value = config.Value ?? string.Empty,
                    DataType = config.DataType ?? "string",
                    Description = config.Description
                };

                var validationResult = await ValidateCreateAsync(createDto);
                if (!validationResult.IsValid)
                {
                    result.Merge(validationResult);
                }
            }

            // 检查批量操作的业务规则
            ValidateBatchBusinessRules(configurations, result);

            return result;
        }

        private void ValidateBasicRules(CreateConfigurationItemDto input, ConfigurationValidationResult result)
        {
            // 命名空间验证
            if (string.IsNullOrWhiteSpace(input.Namespace))
            {
                result.AddError("命名空间不能为空");
            }
            else if (input.Namespace.Length > ConfigurationItemConsts.MaxNamespaceLength)
            {
                result.AddError($"命名空间长度不能超过{ConfigurationItemConsts.MaxNamespaceLength}个字符");
            }
            else if (!Regex.IsMatch(input.Namespace, @"^[a-zA-Z][a-zA-Z0-9._-]*$"))
            {
                result.AddError("命名空间必须以字母开头，只能包含字母、数字、点、下划线和短横线");
            }

            // 配置键验证
            if (string.IsNullOrWhiteSpace(input.Key))
            {
                result.AddError("配置键不能为空");
            }
            else if (input.Key.Length > ConfigurationItemConsts.MaxKeyLength)
            {
                result.AddError($"配置键长度不能超过{ConfigurationItemConsts.MaxKeyLength}个字符");
            }
            else if (!Regex.IsMatch(input.Key, @"^[a-zA-Z][a-zA-Z0-9._-]*$"))
            {
                result.AddError("配置键必须以字母开头，只能包含字母、数字、点、下划线和短横线");
            }

            // 配置值验证
            if (string.IsNullOrWhiteSpace(input.Value))
            {
                result.AddError("配置值不能为空");
            }
            else if (input.Value.Length > ConfigurationItemConsts.MaxValueLength)
            {
                result.AddError($"配置值长度不能超过{ConfigurationItemConsts.MaxValueLength}个字符");
            }

            // 值类型验证
            if (string.IsNullOrWhiteSpace(input.DataType))
            {
                result.AddError("值类型不能为空");
            }
            else if (!IsValidDataType(input.DataType))
            {
                result.AddError("值类型必须是支持的类型：string, int(int32), long(int64), bool(boolean), double, decimal, float(single), datetime, guid, json, object, array");
            }

            // 描述验证
            if (input.Description?.Length > ConfigurationItemConsts.MaxDescriptionLength)
            {
                result.AddError($"描述长度不能超过{ConfigurationItemConsts.MaxDescriptionLength}个字符");
            }
        }

        private void ValidateBasicRulesForUpdate(UpdateConfigurationItemDto input, ConfigurationValidationResult result)
        {
            // 配置值验证
            if (string.IsNullOrWhiteSpace(input.Value))
            {
                result.AddError("配置值不能为空");
            }
            else if (input.Value.Length > ConfigurationItemConsts.MaxValueLength)
            {
                result.AddError($"配置值长度不能超过{ConfigurationItemConsts.MaxValueLength}个字符");
            }

            // 值类型验证
            if (string.IsNullOrWhiteSpace(input.DataType))
            {
                result.AddError("值类型不能为空");
            }
            else if (!IsValidDataType(input.DataType))
            {
                result.AddError("值类型必须是支持的类型：string, int(int32), long(int64), bool(boolean), double, decimal, float(single), datetime, guid, json, object, array");
            }

            // 描述验证
            if (input.Description?.Length > ConfigurationItemConsts.MaxDescriptionLength)
            {
                result.AddError($"描述长度不能超过{ConfigurationItemConsts.MaxDescriptionLength}个字符");
            }
        }

        private async Task ValidateBusinessRulesAsync(CreateConfigurationItemDto input, ConfigurationValidationResult result)
        {
            // 检查重复性
            var existingConfig = await _configurationRepository.FirstOrDefaultAsync(x =>
                x.Namespace == input.Namespace && x.Key == input.Key);

            if (existingConfig != null)
            {
                result.AddError($"配置项 '{input.Namespace}:{input.Key}' 已存在");
            }

            // 检查命名空间限制
            if (SystemNamespaces.Contains(input.Namespace.ToLowerInvariant()))
            {
                result.AddWarning($"不建议使用系统保留命名空间 '{input.Namespace}'");
            }

            // 检查命名空间的配置数量限制
            var namespaceConfigCount = await _configurationRepository.CountAsync(x => x.Namespace == input.Namespace);
            if (namespaceConfigCount >= 1000)
            {
                result.AddError($"命名空间 '{input.Namespace}' 的配置项数量已达到限制（1000个）");
            }
        }

        private void ValidateBusinessRulesForUpdate(
            ConfigurationItem existingConfig,
            UpdateConfigurationItemDto input,
            ConfigurationValidationResult result)
        {
            // 检查值类型变更
            if (existingConfig.DataType.ToLowerInvariant() != input.DataType.ToLowerInvariant())
            {
                if (!CanChangeDataType(existingConfig.DataType, input.DataType, input.Value))
                {
                    result.AddError($"不能将数据类型从 {existingConfig.DataType} 更改为 {input.DataType}");
                }
            }
        }

        private void ValidateSecurityRules(CreateConfigurationItemDto input, ConfigurationValidationResult result)
        {
            // 检查敏感配置
            if (IsSensitiveConfiguration(input.Key))
            {
                result.AddWarning($"配置 '{input.Key}' 可能包含敏感信息，建议使用加密存储");
            }

            // 检查配置值的安全性
            ValidateValueSecurity(input.Value, input.DataType, result);
        }

        private void ValidateSecurityRulesForUpdate(
            ConfigurationItem existingConfig,
            UpdateConfigurationItemDto input,
            ConfigurationValidationResult result)
        {
            // 检查敏感配置
            if (IsSensitiveConfiguration(existingConfig.Key))
            {
                if (input.Value != existingConfig.Value)
                {
                    result.AddWarning($"正在修改敏感配置 '{existingConfig.Key}'，请确保操作的安全性");
                }
            }

            // 检查配置值的安全性
            ValidateValueSecurity(input.Value, input.DataType, result);
        }

        private void ValidateValueSecurity(string value, string valueType, ConfigurationValidationResult result)
        {
            // 检查是否包含潜在危险内容
            if (value.Contains("javascript:", StringComparison.OrdinalIgnoreCase) ||
                value.Contains("<script", StringComparison.OrdinalIgnoreCase))
            {
                result.AddWarning("配置值可能包含潜在的脚本注入风险");
            }

            // 检查是否包含SQL注入模式
            var sqlPatterns = new[]
            {
                "drop table", "delete from", "insert into", "update set", "union select",
                "exec(", "execute(", "xp_cmdshell"
            };

            foreach (var pattern in sqlPatterns)
            {
                if (value.IndexOf(pattern, StringComparison.OrdinalIgnoreCase) >= 0)
                {
                    result.AddWarning($"配置值可能包含潜在的SQL注入风险: {pattern}");
                    break;
                }
            }
        }

        private async Task ValidateDependenciesAsync(ConfigurationItem config, ConfigurationValidationResult result)
        {
            // 检查是否有其他配置依赖此配置
            // 这里可以实现更复杂的依赖关系检查逻辑
            _logger.LogDebug("检查配置项 {ConfigKey} 的依赖关系", $"{config.Namespace}:{config.Key}");
        }

        private void ValidateBatchBusinessRules(List<BatchConfigurationItemDto> configurations, ConfigurationValidationResult result)
        {
            // 检查批量操作的大小限制
            if (configurations.Count > 100)
            {
                result.AddError("批量操作的配置项数量不能超过100个");
            }

            // 检查重复键
            var duplicateKeys = configurations
                .GroupBy(x => $"{x.Namespace}:{x.Key}")
                .Where(g => g.Count() > 1)
                .Select(g => g.Key)
                .ToList();

            foreach (var duplicateKey in duplicateKeys)
            {
                result.AddError($"批量操作中存在重复的配置键: {duplicateKey}");
            }
        }

        private static bool IsValidDataType(string dataType)
        {
            return dataType.ToLowerInvariant() switch
            {
                // 基础类型
                "string" => true,
                "int" => true,
                "int32" => true,
                "long" => true,
                "int64" => true,
                "bool" => true,
                "boolean" => true,
                "double" => true,
                "decimal" => true,
                "float" => true,
                "single" => true,

                // 特殊类型
                "datetime" => true,
                "date" => true,
                "guid" => true,
                "json" => true,

                // 其他常见类型
                "object" => true,
                "array" => true,

                _ => false
            };
        }

        private static bool IsSensitiveConfiguration(string key)
        {
            return SensitiveKeyPatterns.Any(pattern => pattern.IsMatch(key));
        }

        private static bool IsSystemCriticalConfig(ConfigurationItem config)
        {
            var systemCriticalKeys = new[]
            {
                "system:database:connectionstring",
                "system:security:encryptionkey",
                "system:authentication:secret",
                "abp:connectionstrings:default"
            };

            var configKey = $"{config.Namespace}:{config.Key}";
            return systemCriticalKeys.Contains(configKey, StringComparer.OrdinalIgnoreCase);
        }

        private static bool CanChangeDataType(string oldType, string newType, string newValue)
        {
            var oldTypeLower = oldType.ToLowerInvariant();
            var newTypeLower = newType.ToLowerInvariant();

            // 相同类型可以变更
            if (oldTypeLower == newTypeLower)
                return true;

            // 可以从string转换为其他类型（如果值有效）
            if (oldTypeLower == "string")
            {
                return newTypeLower switch
                {
                    "int" => int.TryParse(newValue, out _) || long.TryParse(newValue, out _),
                    "bool" => bool.TryParse(newValue, out _) ||
                              newValue.Equals("true", StringComparison.OrdinalIgnoreCase) ||
                              newValue.Equals("false", StringComparison.OrdinalIgnoreCase) ||
                              newValue.Equals("1") || newValue.Equals("0"),
                    "double" => double.TryParse(newValue, out _) || decimal.TryParse(newValue, out _),
                    "decimal" => decimal.TryParse(newValue, out _),
                    "datetime" => DateTime.TryParse(newValue, out _) ||
                                   DateTimeOffset.TryParse(newValue, out _) ||
                                   long.TryParse(newValue, out _),
                    "guid" => Guid.TryParse(newValue, out _),
                    "json" => IsValidJson(newValue),
                    _ => false
                };
            }

            return false;
        }

        private static bool IsValidJson(string json)
        {
            try
            {
                System.Text.Json.JsonDocument.Parse(json);
                return true;
            }
            catch
            {
                return false;
            }
        }
    }
}